package com.supermap.localization.impl;

import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.supermap.localization.api.FileExtracter;
import com.supermap.localization.api.LineExtracter;
import com.supermap.localization.commontypes.SampleInfo;
import com.supermap.localization.util.MapUtil;

public class FileExtracterImpl implements FileExtracter {

    private LineExtracter lineExtracter;

    public void setLineExtracter(LineExtracter lineExtracter) {
        this.lineExtracter = lineExtracter;
    }

    @Override
    public List<SampleInfo> extract(Path path) throws Exception {
        List<SampleInfo> allLineSamples = extractAllFile(path);
        List<SampleInfo> perLineSamples = extractPerLine(path);
        return combineSample(perLineSamples, allLineSamples);
    }

    private List<SampleInfo> extractPerLine(Path path) throws Exception {
        Map<String, SampleInfo> fileSamples = new HashMap<>();
        BufferedReader br = null;
        br = Files.newBufferedReader(path, StandardCharsets.UTF_8);
        String line = null;
        int lineNum = 1;
        StringBuffer sb = new StringBuffer();
        try {
            while ((line = br.readLine()) != null) {
                sb = sb.append("\n" + line);
                List<String> lineSample = lineExtracter.extract(line);
                List<SampleInfo> sampleInfos = new ArrayList<>();
                for (int i = 0; i < lineSample.size(); i++) {
                    String key = lineSample.get(i);
                    SampleInfo info = new SampleInfo();
                    info.setKey(key);
                    info.setValue(key);
                    info.addLocation(path.toString(), lineNum);
                    sampleInfos.add(info);
                }
                MapUtil.addSampleInfoList(fileSamples, sampleInfos);
                lineNum++;
            }
//            List<String> sbSample = lineExtracter.extract(sb.toString());
//            List<SampleInfo> sampleInfos = new ArrayList<>();
//            for (int i = 0; i < sbSample.size(); i++) {
//                String key = sbSample.get(i);
//                SampleInfo info = new SampleInfo();
//                info.setKey(key);
//                info.setValue(key);
//                info.addLocation(path.toString(), lineNum);
//                sampleInfos.add(info);
//            }
//            MapUtil.addSampleInfoList(fileSamples, sampleInfos);
        } finally {
            br.close();
        }
        return MapUtil.convertToList(fileSamples);
    }

    private List<SampleInfo> extractAllFile(Path path) throws Exception {
        Map<String, SampleInfo> fileSamples = new HashMap<>();
        BufferedReader br = null;
        br = Files.newBufferedReader(path, StandardCharsets.UTF_8);
        String line = null;
        StringBuffer sb = new StringBuffer();
        String lineSeparator = "\n";
        List<String> lineContents = new ArrayList<>();
        try {
            while ((line = br.readLine()) != null) {
                lineContents.add(line);
                sb.append(line);
                sb.append(lineSeparator);
            }
            List<String> lineSample = lineExtracter.extract(sb.toString());
            List<SampleInfo> sampleInfos = new ArrayList<>();
            for (int i = 0; i < lineSample.size(); i++) {
                String key = lineSample.get(i);
                SampleInfo info = new SampleInfo();
                info.setKey(key);
                info.setValue(key);
                info.addLocation(path.toString(), 1);
                sampleInfos.add(info);
            }
            MapUtil.addSampleInfoList(fileSamples, sampleInfos);
        } finally {
            br.close();
        }
        return MapUtil.convertToList(fileSamples);
    }

    private List<SampleInfo> combineSample(List<SampleInfo> perLineSample, List<SampleInfo> allLineSample) {
        for (int i = 0; i < allLineSample.size(); i++) {
            int index = getIndex(allLineSample.get(i), perLineSample);
            if (index >= 0) {
                allLineSample.set(i, perLineSample.get(index));
            }
        }
        return allLineSample;
    }

    private int getIndex(SampleInfo sample, List<SampleInfo> sampleList) {
        int index = -1;
        for (int i = 0; i < sampleList.size(); i++) {
            if (sampleList.get(i).getKey().equals(sample.getKey())) {
                index = i;
                break;
            }
        }
        return index;
    }

}
